package br.com.mtg.movethegarbage.graphics;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

import br.com.mtg.movethegarbage.framework.Graphics;

public class Vertices
{
	final Graphics graphics;
	final boolean hasColor;
	final boolean hasTexCoords;
	final int vertexSize;
	final IntBuffer vertices;
	final int[] tmpBuffer;
	final ShortBuffer indices;

	public Vertices(Graphics _graphics, int maxVertices, int maxIndices, boolean _hasColor, boolean _hasTexCoords)
	{
		graphics = _graphics;
		hasColor = _hasColor;
		hasTexCoords = _hasTexCoords;
		vertexSize = (2 + (hasColor ? 4 : 0) + (hasTexCoords ? 2 : 0)) * 4;
		tmpBuffer = new int[maxVertices * vertexSize / 4];

		ByteBuffer buffer = ByteBuffer.allocateDirect(maxVertices * vertexSize);
		buffer.order(ByteOrder.nativeOrder());
		vertices = buffer.asIntBuffer();

		if (maxIndices > 0)
		{
			buffer = ByteBuffer.allocateDirect(maxIndices * Short.SIZE / 8);
			buffer.order(ByteOrder.nativeOrder());
			indices = buffer.asShortBuffer();
		}
		else
		{
			indices = null;
		}
	}

	public void setVertices(float[] _vertices, int offset, int length)
	{
		vertices.clear();
		int len = offset + length;
		for (int i = offset, j = 0; i < len; i++, j++)
			tmpBuffer[j] = Float.floatToRawIntBits(_vertices[i]);
		vertices.put(tmpBuffer, 0, length);
		vertices.flip();
	}

	public void setIndices(short[] _indices, int offset, int length)
	{
		indices.clear();
		indices.put(_indices, offset, length);
		indices.flip();
	}

	public void bind()
	{
		GL10 gl = graphics.getGL();

		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		vertices.position(0);
		gl.glVertexPointer(2, GL10.GL_FLOAT, vertexSize, vertices);

		if (hasColor)
		{
			gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
			vertices.position(2);
			gl.glColorPointer(4, GL10.GL_FLOAT, vertexSize, vertices);
		}

		if (hasTexCoords)
		{
			gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
			vertices.position(hasColor ? 6 : 2);
			gl.glTexCoordPointer(2, GL10.GL_FLOAT, vertexSize, vertices);
		}
	}

	public void draw(int primitiveType, int offset, int numVertices)
	{
		GL10 gl = graphics.getGL();

		if (indices != null)
		{
			indices.position(offset);
			gl.glDrawElements(primitiveType, numVertices, GL10.GL_UNSIGNED_SHORT, indices);
		}
		else
		{
			gl.glDrawArrays(primitiveType, offset, numVertices);
		}
	}

	public void unbind()
	{
		GL10 gl = graphics.getGL();
		if (hasTexCoords)
			gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

		if (hasColor)
			gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
	}
}
